/**
 * 生成 iptables 添加规则指令
 * @author sige
 */
class IptablesRuleAddCmdGenerator {
    /** */
    constructor ( editModel ) {
        this.model = editModel;
        this.error = null;
        this.cmd = null;
    }

    /** 生成指令 */
    generate() {
        debugger;
        if ( this.isPropertyEmpty('target') && this.isPropertyEmpty('goto') ) {
            this.error = '请配置调用或执行操作';
            return false;
        }

        let cmd = ['sudo iptables'];
        cmd.push('-A'); cmd.push(this.model.chain);
        cmd.push('-t'); cmd.push(this.model.table);
        
        if ( !this.isPropertyEmpty('protocol') ) {
            if ( !this.isPropertyEmpty('!protocol') && true == this.model['!protocol']) {
                cmd.push('!');
            }
            cmd.push(`-p ${this.model.protocol}`);
            cmd = cmd.concat(this.generateArgsFromObject(this.model.protocolConfig));
        }

        if ( !this.isPropertyEmpty('source') ) {
            if ( !this.isPropertyEmpty('!source') && true == this.model['!source']) {
                cmd.push('!');
            }
            cmd.push(`-s ${this.model.source}`);
        }

        if ( !this.isPropertyEmpty('destination') ) {
            if ( !this.isPropertyEmpty('!destination') && true == this.model['!destination']) {
                cmd.push('!');
            }
            cmd.push(`-d ${this.model.destination}`);
        }
        
        if ( !this.isPropertyEmpty('inInterface') ) {
            if ( !this.isPropertyEmpty('!inInterface') && true == this.model['!inInterface']) {
                cmd.push('!');
            }
            cmd.push(`-i ${this.model.inInterface}`);
        }

        if ( !this.isPropertyEmpty('outInterface') ) {
            if ( !this.isPropertyEmpty('!outInterface') && true == this.model['!outInterface']) {
                cmd.push('!');
            }
            cmd.push(`-i ${this.model.outInterface}`);
        }
        
        cmd = cmd.concat(this.generateMatchArgs());
        if ( !this.isPropertyEmpty('target') ) {
            cmd.push(`-j ${this.model.target}`);
            cmd = cmd.concat(this.generateArgsFromObject(this.model.targetConfig));
        }
        if ( !this.isPropertyEmpty('goto') ) {
            cmd.push(`-g ${this.model.goto}`);
        }

        this.cmd = cmd.join(' ');
        return true;
    }

    /** 判断属性是否为空 */
    isPropertyEmpty( name ) {
        if ( undefined == this.model[name] 
        || null == this.model[name]
        || ( 'object' == typeof(this.model[name]) && 0 == Object.keys(this.model.source).length )
        || ( 'string' == typeof(this.model[name]) && '' == this.model[name].trim()) 
        ) {
            return true;
        }
        return false;
    }

    /** 生成匹配相关参数 */
    generateMatchArgs() {
        if ( undefined == this.model.matches ) {
            return [];
        }

        let cmd = [];
        for ( let i=0; i<this.model.matches.length; i++ ) {
            let match = this.model.matches[i];
            cmd.push(`-m ${match.module}`);
            cmd = cmd.concat(this.generateArgsFromObject(match.config));
        }
        return cmd;
    }

    /** 根据对象生成参数列表 */
    generateArgsFromObject( argObj ) {
        let cmd = [];
        for ( let key in argObj ) {
            if ( '!' == key[0] ) {
                continue;
            }
            let paramKey = key;
            let paramValue = argObj[key];
            if ( -1 != paramKey.indexOf('@') ) {
                paramValue = this.generateArgsFromObjectGetArray(argObj, paramKey);
                paramKey = paramKey.substring(0, paramKey.indexOf('@'));
            }
            
            let reverseKey = `!${key}`;
            if ( undefined != argObj[reverseKey] && true == argObj[reverseKey] ) {
                cmd.push('!');
            }
            
            if ( null == paramValue ) {
                continue;
            }

            cmd.push(key);
            if ( true == paramValue ) {
                // nothing to do here.
            } else {
                cmd.push(paramValue);
            }
        }
        return cmd;
    }

    /** 获取数组参数 */
    generateArgsFromObjectGetArray( argObj, key ) {
        let index = key.substring(key.indexOf('@')+1);
        if ( '0' != index ) {
            return null;
        }
        key = key.substring(0, key.indexOf('@'));
        let paramValue = [];
        while ( true ) {
            let pkey = `${key}@${index}`;
            if ( undefined == argObj[pkey] ) {
                break;
            }
            let pval = argObj[pkey];
            if ( 'object' == typeof(pval) ) {
                pval = pval.join(',');
            }
            paramValue.push(pval);
            index ++;
        }
        paramValue = paramValue.join(' ');
        if ( "" == paramValue.trim() ) {
            paramValue = null;
        }
        return paramValue;
    }
}

export default IptablesRuleAddCmdGenerator;